💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    Django(todoList) 3 genericAPI로 변경 | ✅ 저자: 이유정(박사)

    [feat] django (Day 3)
    -  GenericAPIView
    -  Edit urls.py
    -  Edit apis.py
    -  imsomnia
    

    todo > urls.py

    urlpatterns = [
    	# APIView
    
    	# GenericAPIView
    	path("generics/create/", TodoGenericsCreateAPI.as_view()),
    	path("generics/list/", TodoGenericsListAPI.as_view()),
    	path("generics/retrieve/<int:pk>/", TodoGenericsRetrieveAPI.as_view()),
    	path("generics/update/<int:pk>/", TodoGenericsUpdateAPI.as_view()),
    	path("generics/delete/<int:pk>/", TodoGenericsDeleteAPI.as_view()),
    ]
    

    .post('/todo/generics/create/', data) .patch(/todo/generics/update/${pk}/, payload) .get(/todo/generics/retrieve/${pk}/) .delete(/todo/generics/delete/${pk}/) .get(/todo/generics/retrieve/${pk}/) .get(/todo/generics/list/?page=${page}) axiosInstance.patch(/todo/generics/update/${id}/

    todo > api_views.py

    # generics을 위해 모듈추가
    from rest_framework import generics
    # from rest_framework import status, generics 
    # -> 같은 모듈안에 있으므로 합치기
    
    # REST Framework_GenericAPIView        
    class TodoGenericsListAPI(generics.ListAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
    
    class TodoGenericsCreateAPI(generics.CreateAPIView):
    	serializer_class = TodoSerializer
    
    class TodoGenericsRetrieveAPI(generics.RetrieveAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
      
    class TodoGenericsUpdateAPI(generics.UpdateAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
    
    class TodoGenericsDeleteAPI(generics.DestroyAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
    
    # Generics list + create
    class TodoGenericsListCreateAPI(generics.ListCreateAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
    
    # Generics retriver + update + delete
    class TodoGenericsRetrieveUpdateDeleteAPI
    (generics.RetrieveUpdateDestroyAPIView):
    	queryset = Todo.objects.all()
    	serializer_class = TodoSerializer
    

    axiosInstance.patch(/todo/viewsets/view/${id}/ .get(/todo/viewsets/view/${pk}/)


    로그인 로그아웃 직접 로그인/회원가입/로그아웃 화면을 만들고 싶다면?

    • /api-auth/login/ 대신, 자신만의 로그인 폼을 만들고
    • DRF에서 토큰 기반(JWT 등) 로그인 API를 만들거나
    • Session 기반 로그인 처리를 위한 LoginView, LogoutView를 따로 구성해야 합니다.
    # config/urls.py
    path('api-auth/', include('rest_framework.urls')),
    
    # config/settings.py
    LOGIN_REDIRECT_URL = '/todo/list/'
    

    단순한 로그아웃 → Django 기본 logout() 함수 + URL 연결만으로 충분합니다. header.html

    {% load static %}
    <div>
        <h1> Todo List</h1>
        <div>
          <a href="{% url 'todo_List' %}">목록</a>
          {% if user.is_authenticated%}
            <button><a href="{% url 'custom-logout' %}">로그아웃</a></button>
          {%else%}  
            <a href="{% url 'rest_framework:login' %}?next={% url 'todo_List'%}">로그인</a>
          {%endif%}
        </div>
    </div>
    

    단순구조방식

    # todo/urls.py
    # ViewSet
    path("api/custom-logout/", api_views.CustomLogoutAPI.as_view(), name="custom_logout"),
    
    # todo/api_views.py
    from django.contrib.auth import logout
    
    class CustomLogoutAPI(APIView):
        def get(self, request):  
            logout(request)
            # return Response({"message": "로그아웃 완료"}, status=status.HTTP_200_OK)
            return redirect('todo_List')
    

    Vue/React SPA처럼 REST API 중심 구조라면 axios 방식으로 처리해야 합니다.

    // templates/header.html
    
    {% load static %}
    <div class="header">
      <h1>Todo List</h1>
      <div class="user-actions">
        <a href="{% url 'todo_List' %}" class="nav-link">📋 목록</a>
    
        {% if user.is_authenticated %}
          <!-- 🔓 로그아웃 버튼 (id 추가) -->
          {% comment %} <button><a href="{% url 'custom-logout' %}">로그아웃</a></button>  {% endcomment %}
            <button id="logoutBtn">로그아웃</button>
        {% else %}
          <!-- 🔒 로그인은 여전히 DRF 기본 로그인 뷰 사용 -->
          <a
            href="{% url 'rest_framework:login' %}?next={% url 'todo_List' %}"
            class="nav-link login"
          >🔒 로그인</a>
        {% endif %}
      </div>
    </div>
    
    <script>
    document.addEventListener("DOMContentLoaded", () => {
      document.getElementById("logoutBtn").addEventListener("click", () => {
        axiosInstance.get("/todo/api/custom-logout/")
          .then(() => {
            window.location.href = "{% url 'todo_List' %}";
          })
          .catch(err => {
            console.error("로그아웃 실패:", err);
            alert("로그아웃 중 오류가 발생했습니다.");
          });
      });
    });
    </script>
    

    실제로 언제 어떤 걸 써야 하나요?

    • 단순한 로그아웃 → Django 기본 logout() 함수 + URL 연결만으로 충분합니다.
    • axios로 로그아웃을 처리하려면 CustomLogoutAPI 같은 POST용 API 뷰를 추가로 만들어야 하며, 자바스크립트에서 호출해야 합니다.

    만약 템플릿 기반 + 세션 로그인이라면, 굳이 복잡하게 axiosInstance.post()를 만들 필요는 없습니다.
    반대로 Vue/React SPA처럼 REST API 중심 구조라면 axios 방식이 더 자연스럽습니다.

    TOP
    preload preload